/*!
 * 界面视图模块  
 */

layui.define(['laytpl', 'layer'], function (exports) {
    var $ = layui.jquery,
        laytpl = layui.laytpl,
        layer = layui.layer,
        setter = layui.setter,
        device = layui.device(),
        hint = layui.hint()

        //对外接口
        ,
        view = function (id) {
            return new Class(id);
        }

        ,
        SHOW = 'layui-show',
        LAY_BODY = 'LAY_app_body'

        //构造器
        ,
        Class = function (id) {
            this.id = id;
            this.container = $('#' + (id || LAY_BODY));
        };

    //加载中
    view.loading = function (elem) {
        elem.append(
            this.elemLoad = $('<i class="layui-anim layui-anim-rotate layui-anim-loop layui-icon layui-icon-loading layadmin-loading"></i>')
        );
    };

    //移除加载
    view.removeLoad = function () {
        this.elemLoad && this.elemLoad.remove();
    };

    //清除 token，并跳转到登入页
    view.exit = function (callback) {
        //清空本地记录的 token
        layui.sessionData(setter.tableName, { key: setter.request.tokenName, remove: true });
        layui.sessionData(setter.tableName, { key: 'UserInfo', remove: true });
        layui.sessionData(setter.tableName, { key: 'OpenTabs', remove: true });
        window.sessionStorage.getItem("lockcms") == false;
        //跳转到登入页
        let x_name = "/";
        let index = top.location.pathname.indexOf('index.html');
        if (index == -1) {
            x_name = top.location.pathname;
        } else {
            x_name = top.location.pathname.substring(0, index);
        }
        top.location.href = top.location.origin + x_name + 'login.html';
        callback && callback();
    };
    var isagainLogin = true;
    view.againLogin = function (isCurrPage) {
        if (isagainLogin) {
            isagainLogin = false;
        } else {
            return;
        }
        parent.layer.msg('登入过期', {
            offset: '15px',
            icon: 1,
            time: 2000
        }, function () {
            parent.layer.prompt({
                id: 'expire_window',
                title: '登录过期,请重新输入密码',
                formType: 1,
                btn: ['确定', '取消'],
                anim: 4,
                cancel: function () { view.exit(); },
                btn2: function () { view.exit() }
            }, function (text, index) {
                $.ajax({
                    type: 'post',
                    url: setter.baseUrl + '/api/Login/Login',
                    data: { 'UserName': layui.sessionData(setter.tableName)["UserInfo"].user.cUserName, 'Password': text },
                    success: function (res) {
                        if (res.code == 200) {
                            layui.sessionData(setter.tableName, {
                                key: setter.request.tokenName,
                                value: res.data.auth_token.token_type + ' ' + res.data.auth_token.ticket
                            });
                            parent.layer.close(index);
                            if (isCurrPage) {
                                location.reload();
                            } else {
                                location.reload();
                                parent.location.reload();
                            }
                        } else {
                            parent.layer.msg(res.msg)
                        }
                    }
                });
            });
        });
    }

    //Ajax请求
    view.req = function (options) {
        var that = this,
            success = options.success,
            error = options.error,
            request = setter.request,
            response = setter.response,
            debug = function () {
                return setter.debug ?
                    '<br><cite>URL：</cite>' + options.url :
                    '';
            };
        var loginLoading = parent.layer.msg('加载中，请稍候', { id: 'loginloadingID', icon: 16, time: false, shade: 0.1 });
        options.data = options.data || {};
        options.headers = options.headers || {};
        options.url = setter.baseUrl + options.url;

        if (request.tokenName) {
            var sendData = typeof options.data === 'string' ?
                JSON.parse(options.data) :
                options.data;

            //自动给 Request Headers 传入 token
            options.headers[request.tokenName] = request.tokenName in options.headers ?
                options.headers[request.tokenName] :
                (layui.sessionData(setter.tableName)[request.tokenName] || '');
        }

        delete options.success;
        delete options.error;

        return $.ajax($.extend({
            type: 'get',
            dataType: 'json',
            success: function (res) {
                parent.layer.close(loginLoading);
                var statusCode = response.statusCode;
                //只有 response 的 code 一切正常才执行 done
                if (res[response.statusName] == statusCode.ok) {
                    typeof options.done === 'function' && options.done(res);
                }
                //登录状态失效，清除本地 access_token，并强制跳转到登入页
                else if (res[response.statusName] == statusCode.logout) {
                    view.againLogin(false);
                }
                //其它异常
                else if (res[response.statusName] == -1) {
                    var errorText = [
                        '<cite>Error：</cite> ' + (res[response.msgName] || '返回状态码异常'), debug()
                    ].join('');
                    view.error(errorText);
                }
                //只要 http 状态码正常，无论 response 的 code 是否正常都执行 success
                typeof success === 'function' && success(res);
            },
            error: function (e, code) {
                parent.layer.close(loginLoading);
                if (e.status == 401) {
                    if (!layui.sessionData(setter.tableName)["UserInfo"]) {
                        view.exit();
                    } else {
                        parent.layer.msg('登入过期', {
                            id: 'loginErroID',
                            icon: 2,
                            time: 2000
                        }, function () {
                            view.exit();
                        });
                    }
                }
                else if (e.status == 403) {
                    layer.msg('没有权限！', {
                        icon: 2,
                        time: 2000
                    });
                } else if (this.status == 429) {
                    layer.msg('请求频繁！', {
                        icon: 2,
                        time: 2000
                    });
                } else {
                    var errorText = [
                        '请求异常，请重试<br><cite>错误信息：</cite>' + code, debug()
                    ].join('');
                    if (setter.debug) view.error(errorText);
                }
                typeof error === 'function' && error.apply(this, arguments);
            }
        }, options));
    };
    //Ajax请求
    view.export = function (options) {
        var that = this,
            success = options.success,
            request = setter.request;

        var loginLoading = parent.layer.msg('加载中，请稍候', { id: 'loginloadingID', icon: 16, time: false, shade: 0.1 });
        var xhr = new XMLHttpRequest();
        xhr.open('GET', setter.baseUrl + options.url + "?" + new URLSearchParams(options.data).toString());
        xhr.responseType = 'blob';
        xhr.setRequestHeader(request.tokenName, layui.sessionData(setter.tableName)[request.tokenName]);
        xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        xhr.onreadystatechange = function () {
            parent.layer.close(loginLoading);
            if (this.readyState == 4 && this.status == 200) {
                let blob = new Blob([this.response], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
                let objUrl = URL.createObjectURL(blob);
                window.location.href = objUrl;
                window.URL.revokeObjectURL(objUrl);
            } else {
                if (this.status == 401) {
                    if (!layui.sessionData(setter.tableName)["UserInfo"]) {
                        view.exit();
                    } else {
                        parent.layer.msg('登入过期', {
                            id: 'loginErroID',
                            icon: 2,
                            time: 2000
                        }, function () {
                            view.exit();
                        });
                    }
                }
                if (this.status == 403) {
                    layer.msg('没有权限！', {
                        icon: 2,
                        time: 2000
                    });
                }
                if (this.status == 429) {
                    layer.msg('请求频繁！', {
                        icon: 2,
                        time: 2000
                    });
                }
            }
        }
        xhr.send();
    },
    view.down = function (options) {
            var that = this,
                success = options.success,
                request = setter.request;
            var index = options.data.url.lastIndexOf("\\");
            if (index == -1) {
                index = options.data.url.lastIndexOf("/");
            }
            var strFileName = options.data.url.substring(index + 1);

            //var loginLoading = parent.layer.msg('加载中，请稍候', { icon: 16, time: false, shade: 0.1 });
            var xhr = new XMLHttpRequest();
            xhr.open('GET', setter.baseUrl + "/api/base/down?url=" + options.data.url);
            xhr.responseType = 'blob';
            xhr.setRequestHeader(request.tokenName, layui.sessionData(setter.tableName)[request.tokenName]);
            xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
            xhr.onreadystatechange = function () {
                if (this.readyState == 4 && this.status == 200) {
                    //parent.layer.close(loginLoading);
                    var a = document.createElement('a');
                    a.href = window.URL.createObjectURL(this.response);
                    a.download = strFileName;
                    a.click();
                } else {
                    if (this.status == 401) {
                        if (!layui.sessionData(setter.tableName)["UserInfo"]) {
                            view.exit();
                        } else {
                            parent.layer.msg('登入过期', {
                                id: 'loginErroID',
                                icon: 2,
                                time: 2000
                            }, function () {
                                view.exit();
                            });
                        }
                    }
                    if (this.status == 403) {
                        layer.msg('没有权限！', {
                            icon: 2,
                            time: 2000
                        });
                    }
                    if (this.status == 429) {
                        layer.msg('请求频繁！', {
                            icon: 2,
                            time: 2000
                        });
                    }
                }
            }
            xhr.send();
        }
    //弹窗
    view.popup = function (options) {
        var success = options.success,
            skin = options.skin;

        delete options.success;
        delete options.skin;

        return layer.open($.extend({
            type: 1,
            title: '提示',
            content: '',
            id: 'LAY-system-view-popup',
            skin: 'layui-layer-admin' + (skin ? ' ' + skin : ''),
            shadeClose: true,
            closeBtn: false,
            success: function (layero, index) {
                var elemClose = $('<i class="layui-icon" close>&#x1006;</i>');
                layero.append(elemClose);
                elemClose.on('click', function () {
                    layer.close(index);
                });
                typeof success === 'function' && success.apply(this, arguments);
            }
        }, options))
    };

    //异常提示
    view.error = function (content, options) {
        return view.popup($.extend({
            content: content,
            //,shade: 0.01
            offset: 'auto',
            anim: 6,
            area: ['500px', '300px'],
            id: 'LAY_adminError'
        }, options))
    };


    //请求模板文件渲染
    Class.prototype.render = function (views, params) {
        var that = this,
            router = layui.router();
        views = setter.views + views + setter.engine;

        $('#' + LAY_BODY).children('.layadmin-loading').remove();
        view.loading(that.container); //loading
        //请求模板
        $.ajax({
            url: views,
            type: 'get',
            dataType: 'html',
            data: {
                v: layui.cache.version
            },
            success: function (html) {
                html = '<div>' + html + '</div>';
                var elemTitle = $(html).find('title'),
                    title = elemTitle.text() || (html.match(/\<title\>([\s\S]*)\<\/title>/) || [])[1];

                var res = {
                    title: title,
                    body: html
                };

                elemTitle.remove();
                that.params = params || {}; //获取参数

                if (that.then) {
                    that.then(res);
                    delete that.then;
                }

                that.parse(html);
                view.removeLoad();

                if (that.done) {
                    that.done(res);
                    delete that.done;
                }

            },
            error: function (e) {
                view.removeLoad();
                if (that.render.isError) {
                    return view.error('请求视图文件异常，状态：' + e.status);
                };

                if (e.status === 404) {
                    that.render('template/tips/404');
                } else {
                    that.render('template/tips/error');
                }

                that.render.isError = true;
            }
        });
        return that;
    };

    //解析模板
    Class.prototype.parse = function (html, refresh, callback) {
        var that = this,
            isScriptTpl = typeof html === 'object' //是否模板元素
            ,
            elem = isScriptTpl ? html : $(html),
            elemTemp = isScriptTpl ? html : elem.find('*[template]'),
            fn = function (options) {
                var tpl = laytpl(options.dataElem.html()),
                    res = $.extend({
                        params: router.params
                    }, options.res);

                options.dataElem.after(tpl.render(res));
                typeof callback === 'function' && callback();

                try {
                    options.done && new Function('d', options.done)(res);
                } catch (e) {
                    console.error(options.dataElem[0], '\n存在错误回调脚本\n\n', e)
                }
            },
            router = layui.router();

        elem.find('title').remove();
        that.container[refresh ? 'after' : 'html'](elem.children());

        router.params = that.params || {};

        //遍历模板区块
        for (var i = elemTemp.length; i > 0; i--) {
            (function () {
                var dataElem = elemTemp.eq(i - 1),
                    layDone = dataElem.attr('lay-done') || dataElem.attr('lay-then') //获取回调
                    ,
                    url = laytpl(dataElem.attr('lay-url') || '').render(router) //接口 url
                    ,
                    data = laytpl(dataElem.attr('lay-data') || '').render(router) //接口参数
                    ,
                    headers = laytpl(dataElem.attr('lay-headers') || '').render(router); //接口请求的头信息

                try {
                    data = new Function('return ' + data + ';')();
                } catch (e) {
                    hint.error('lay-data: ' + e.message);
                    data = {};
                };

                try {
                    headers = new Function('return ' + headers + ';')();
                } catch (e) {
                    hint.error('lay-headers: ' + e.message);
                    headers = headers || {}
                };

                if (url) {
                    view.req({
                        type: dataElem.attr('lay-type') || 'get',
                        url: url,
                        data: data,
                        dataType: 'json',
                        headers: headers,
                        success: function (res) {
                            fn({
                                dataElem: dataElem,
                                res: res,
                                done: layDone
                            });
                        }
                    });
                } else {
                    fn({
                        dataElem: dataElem,
                        done: layDone
                    });
                }
            }());
        }

        return that;
    };

    //自动渲染数据模板
    Class.prototype.autoRender = function (id, callback) {
        var that = this;
        $(id || 'body').find('*[template]').each(function (index, item) {
            var othis = $(this);
            that.container = othis;
            that.parse(othis, 'refresh');
        });
    };

    //直接渲染字符
    Class.prototype.send = function (views, data) {
        var tpl = laytpl(views || this.container.html()).render(data || {});
        this.container.html(tpl);
        return this;
    };

    //局部刷新模板
    Class.prototype.refresh = function (callback) {
        var that = this,
            next = that.container.next(),
            templateid = next.attr('lay-templateid');

        if (that.id != templateid) return that;

        that.parse(that.container, 'refresh', function () {
            that.container.siblings('[lay-templateid="' + that.id + '"]:last').remove();
            typeof callback === 'function' && callback();
        });

        return that;
    };

    //视图请求成功后的回调
    Class.prototype.then = function (callback) {
        this.then = callback;
        return this;
    };

    //视图渲染完毕后的回调
    Class.prototype.done = function (callback) {
        this.done = callback;
        return this;
    };

    //对外接口
    exports('view', view);
});